package edu.cug.water.crawler.job.task.committee;


import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import edu.cug.water.crawler.common.annotation.BeanField;
import edu.cug.water.crawler.common.constant.Constant;
import edu.cug.water.crawler.common.constant.EsConstants;
import edu.cug.water.crawler.common.exception.RRException;
import edu.cug.water.crawler.common.utils.DateUtils;
import edu.cug.water.crawler.common.utils.EsUtils;
import edu.cug.water.crawler.job.entity.committee.ChangJiang;
import edu.cug.water.crawler.job.request.RequestUtil;
import edu.cug.water.crawler.job.task.ITask;
import edu.cug.water.crawler.job.utils.AbstractCrawlerTask;
import edu.cug.water.crawler.job.utils.DataConvertUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import java.io.IOException;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Component("job:ChangJiang")
@Slf4j
public class ChangJiangTask extends AbstractCrawlerTask<ChangJiang> implements ITask {

    private static final String REGEX = "sssq = (.*);.*var sqHtml";
    static final Pattern pattern = Pattern.compile(REGEX, Pattern.DOTALL);

    @Autowired
    private EsUtils esUtils;

    @Autowired
    private RequestUtil requestUtil;

    @Override
    public int run(String params) throws IOException {
        init();
        ResponseEntity<String> response = getRequestBody();

        List<ChangJiang> list = getDataFromStr(response.getBody());

        String s = esUtils.addDocuments(EsConstants.TypeConstant.CHANG_JIANG_COMMITTEE.getValue(), list);
        Boolean aBoolean = esUtils.statusJudge(s);
        if (!aBoolean)
            throw new RRException(getClass().getName() + Constant.LogConstants.THE_PROCESS_OF_ES_STORE_FAILED.getValue());
        return list.size();
    }

    @Override
    protected void init() {
        super.init();
        url = "http://www.cjh.com.cn/sqindex.html";
        headers.set("Host", "www.cjh.com.cn");
        headers.set("Connection", "keep-alive");
        headers.set("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9");
        headers.set("X-Requested-With", "XMLHttpRequest");
        headers.set("Origin", "http://106.37.208.243:8068");
        headers.set("Referer", "http://www.cjh.com.cn/swyb_sssq.html");
        headers.set("Accept-Encoding", "gzip, deflate");
        headers.set("Accept-Language", "en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7");
    }

    @Override
    public ResponseEntity<String> getRequestBody() {
        return requestUtil.get(url, headers);
    }

    @Override
    public List<ChangJiang> getDataFromStr(String requestBody) {
        if (StringUtils.isEmpty(requestBody))
            throw new RRException(getClass().getName() + Constant.LogConstants.RESPONSE_IS_NULL.getValue());

        List<ChangJiang> results = new ArrayList<>();

        Matcher matcher = pattern.matcher(requestBody);
        String jsonStr = null;
        if (matcher.find()) {
            jsonStr = matcher.group(1);
            JSONArray data = (JSONArray) JSONObject.parse(jsonStr);

            for (Object datum : data) {
                JSONObject temp = (JSONObject) datum;

                ChangJiang entity = new ChangJiang();
                Field[] fields = entity.getClass().getDeclaredFields();

                for (Field field : fields) {
                    if (field.getAnnotation(BeanField.class) == null) {
                        continue;
                    }
                    field.setAccessible(true);
                    try {
                        String property = field.getAnnotation(BeanField.class).property();
                        if ("stationCode".equals(field.getName())) {
                            field.set(entity, DataConvertUtil.stationCodeConvert(temp.get(property) + ""));
                        } else {
                            field.set(entity, (temp.get(property) + " ").trim());
                        }
                    } catch (IllegalAccessException e) {
                        throw new RRException(getClass().getName() + Constant.LogConstants.FIELD_ASSIGNMENT_ILLEGAL_ACCESS.getValue());
                    }
                }
                entity.setCreateTime(DateUtils.formatDateTime(new Date()));
                results.add(entity);
            }
        } else {
            log.error("Changjiang Task HTML Regex match failed!");
            throw new RRException(getClass().getName() + Constant.LogConstants.TEXT_REGEX_MATCH_FAILED.getValue());
        }
        return results;
    }
}
